//package middleware
//
//import (
//	"github.com/gin-gonic/gin"
//	"my-systems/pet-system/pkg/e"
//	"my-systems/pet-system/pkg/tools"
//	"net/http"
//	"time"
//)
//
//func JWT() gin.HandlerFunc {
//	return func(c *gin.Context) {
//		code := http.StatusOK
//		token := c.GetHeader("Authorization")
//		if token == "" {
//			code = http.StatusUnauthorized
//		} else {
//			// 验证token
//			claims, err := tools.ParseToken(token)
//			if err != nil {
//				code = e.TokenResolutionFailed // 解析失败
//			} else if time.Now().Unix() > claims.ExpiresAt.Unix() {
//				code = e.TheTokenHasExpired // token过期
//			}
//		}
//		// 若不等于 http.StatusOK，说明在之前的 token 验证过程中出现了问题
//		if code != http.StatusOK {
//			c.JSON(http.StatusOK, gin.H{
//				"code": code,
//				"msg":  e.GetMsgInfo(code),
//			})
//			c.Abort()
//			return
//		}
//		c.Next()
//	}
//}

package middleware

import (
	"github.com/gin-gonic/gin"
	"my-systems/pet-system/pkg/e"
	"my-systems/pet-system/pkg/tools"
	"net/http"
	"sync"
	"time"
)

// TokenBlacklist 定义一个全局的 Token 黑名单
var TokenBlacklist = make(map[string]time.Time)
var BlacklistMutex sync.Mutex

func JWT() gin.HandlerFunc {
	return func(c *gin.Context) {
		code := http.StatusOK
		token := c.GetHeader("Authorization")
		if token == "" {
			code = e.SuspectedTokenDoesNotExist
		} else {
			// 检查token是否在黑名单
			BlacklistMutex.Lock()
			if expiration, exists := TokenBlacklist[token]; exists {
				// 检查是否过期
				if time.Now().Before(expiration) {
					code = e.TheTokenHasExpired // token过期
				} else {
					// 从黑名单中移除
					delete(TokenBlacklist, token)
				}
			}
			BlacklistMutex.Unlock()
			if code == http.StatusOK {
				// 验证token
				claims, err := tools.ParseToken(token)
				if err != nil {
					code = e.TokenResolutionFailed // 解析失败
				} else if time.Now().Unix() > claims.ExpiresAt.Unix() {
					code = e.TheTokenHasExpired // token过期
				} else {
					// 将 claims 存入 gin.Context
					c.Set("claims", claims)
				}
			}
		}
		// 若不等于 http.StatusOK，说明在之前的 token 验证过程中出现了问题
		if code != http.StatusOK {
			c.JSON(http.StatusOK, gin.H{
				"code": code,
				"msg":  e.GetMsgInfo(code),
			})
			c.Abort()
			return
		}
		c.Next()
	}
}
